﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System.Windows;
using System.Windows.Input;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System;
using HouseKeepingPL.HKService;
using System.Windows.Data;
using System.Windows.Documents;
using GalaSoft.MvvmLight.Messaging;

namespace HouseKeepingPL.ViewModel
{
    public class AccountViewModel : ViewModelBase
    {
        private User _currentUser = null; // current user logged

        public AccountViewModel()
        {
            Messenger.Default.Register<ObservableCollection<UserType>>(this,GetUserTypes);
            Messenger.Default.Register<AccountMsgs>(this, UserAccountAction);

            #region relay commands
            //Login relay Commands
            AuthLoginCommand = new RelayCommand(() => AuthLoginCommandExcecute(), () => IsLoginValid);
            LogOutCommand = new RelayCommand(() => LogOutCommandExcecute(), () => IsLoggedIn);
            CreateUserCommand = new RelayCommand(() => CreateUserCommandExcecute(), () => IsLoginValid);
            #endregion
        }


        private void GetUserTypes(ObservableCollection<UserType> userTypes)
        {
            UserTypes = userTypes;
        }

        private void UserAccountAction(AccountMsgs msg)
        {
            if (msg == AccountMsgs.UserDisconnected)
            {
                LogOutCommandExcecute();
            }
        }


        #region login

        public ICommand AuthLoginCommand { get; private set; }


        // generic relay command todo and edmx classes
        private void AuthLoginCommandExcecute(bool isFromCreateUser = false)
        {

            _currentUser = ClientProxy.Proxy.GetUserData(CurrentUserLogin.Username); // user data + incomes + outcomes, single DB access
            if (_currentUser != null)
            {
                if (_currentUser.Password == CurrentUserLogin.Password)
                //if (ClientProxy.Proxy.IsUserAuthenticated(CurrentUserLogin.Username, CurrentUserLogin.Password)) 
                {
                    InitUserSession(isFromCreateUser);
                }
                else
                {
                    MyMessageBox.ErrorOk("Incorrect Username or password!", "Error");
                }
            }
            else
            {
                MyMessageBox.ErrorOk("Username doesn't exists!", "Error");
            }

        }

        private void InitUserSession(bool isFromCreateUser = false)
        {
            if (!isFromCreateUser)
            {

                MyMessageBox.InfoOk(String.Format("Hello, {0}", CurrentUserLogin.Username), "Welcome!");
            }
            else
            {
                TabAccountIndexProperty = 0; // move account tab to login tab
            }
            IsLoggedIn = true;                           // logged in swtich
            CurrentUserLogin.Password = string.Empty;
            Messenger.Default.Send<User>(_currentUser); // shout the user to all the viewmodels
            Messenger.Default.Send<ReportMsgs, ReportViewModel>(ReportMsgs.InitSession); // requests the reports view model to init it's session
            Messenger.Default.Send<AccountMsgs, MainViewModel>(AccountMsgs.UserConnected); // send to the main view model a message - user connected
        }

        /// <summary>
        /// temp user for login and validation purposes
        /// </summary>
        private User _currentUserLogin;
        public User CurrentUserLogin
        {
            get
            {
                if (_currentUserLogin == null)
                {
                    _currentUserLogin = new User();
                    _currentUserLogin.Password = string.Empty;
                    _currentUserLogin.Username = string.Empty;
                }

                RaisePropertyChanged("IsLoginValid");
                return _currentUserLogin;

            }
            set
            {

                _currentUserLogin = value;
                RaisePropertyChanged("CurrentUserLogin");

            }
        }


        private bool _isLoggedIn = false;

        public bool IsLoggedIn
        {
            get { return _isLoggedIn; }
            set
            {

                _isLoggedIn = value;
                 IsLoggedInNeg = !_isLoggedIn;
                 RaisePropertyChanged("IsLoggedIn");
            }

        }
        private bool _isLoggedInNeg =true;

        public bool IsLoggedInNeg
        {
            get { return _isLoggedInNeg; }
            set
            {
                _isLoggedInNeg = value;
                if (_isLoggedInNeg != null)
                {

                    RaisePropertyChanged("IsLoggedInNeg");
                }
            }
        }


        private bool _isLoginValid = false;

        /// <summary>
        /// for validation login, making it impossible to login unless something was entered
        /// </summary>
        public bool IsLoginValid
        {
            get
            {              
                if (CurrentUserLogin != null)
                {
                    if ((CurrentUserLogin.Username != null) && (CurrentUserLogin.Password != null))
                    {
                        if ((!String.IsNullOrWhiteSpace(CurrentUserLogin.Username)) && CurrentUserLogin.Password.Length >= 3)
                            _isLoginValid = true;
                        else
                            _isLoginValid = false;
                    }
                }
                return _isLoginValid;
            }
            set
            {

                // _isLoginValid != _isLoginValid;
                RaisePropertyChanged("IsLoginValid");

            }
        }



        public ICommand LogOutCommand { get; private set; }
        private void LogOutCommandExcecute()
        {
            CurrentUserLogin.Password = string.Empty;    // reset the login user password (for the textboxes)
            CurrentUserLogin.Username = string.Empty;    // reset the login user username (for the textboxes)

            if (_currentUser != null)
            {
                MyMessageBox.InfoOk(String.Format("Goodbye...{0}", _currentUser.Username), "Logged Out");
            }


            // reset

            Messenger.Default.Send<User>(null); // shout null user
            Messenger.Default.Send<ObservableCollection<Income>, IncomesViewModel>(null);
            Messenger.Default.Send<ObservableCollection<Outcome>, OutcomesViewModel>(null);
            Messenger.Default.Send<AccountMsgs, MainViewModel>(AccountMsgs.UserDisconnected); // send to the main view model a message - user disconnected
            IsLoggedIn = false;

        }

        #endregion

        #region Create User
        private ObservableCollection<UserType> _userTypes;
        public ObservableCollection<UserType> UserTypes
        {
            get { return _userTypes; }
            set
            {
                _userTypes = value;
                RaisePropertyChanged("UserTypes");
            }
        }

        private UserType _userType;

        public UserType SelectedUserType
        {
            get { return _userType; }
            set
            {
                _userType = value;
                RaisePropertyChanged("SelectedUserType");
            }
        }

        public ICommand CreateUserCommand { get; private set; }

        private void CreateUserCommandExcecute()
        {
            if (String.IsNullOrEmpty(CurrentUserLogin.Username))
            {
                MyMessageBox.StopOk("Username cannot be left empty!", "Error");
                return;
            }

            if (String.IsNullOrEmpty(CurrentUserLogin.Password))
            {
                MyMessageBox.StopOk("Password cannot be left empty!", "Error");
                return;
            }


            if (ClientProxy.Proxy.IsUsernameTaken(CurrentUserLogin.Username))
            {
                MyMessageBox.InfoOk("Username already taken!\n" +
                                "Please choose another username", "Error");
                return;
            }


            //passed all the validations
            User tempUser = new User()
            {
                Username = CurrentUserLogin.Username,
                Password = CurrentUserLogin.Password,
                UserTypeId = SelectedUserType.Id
            };


            try
            {
                if (ClientProxy.Proxy.InsertUser(tempUser))
                {

                    MyMessageBox.InfoOk(string.Format("User {0}, Created Successfully! \n" +
                                                   "Directing to incomes page", tempUser.Username), "User Created");
                    AuthLoginCommandExcecute(true);
                }
                else
                {
                    MyMessageBox.InfoOk("Username already taken!\n" +
                                    "Please choose another username", "Error");

                }
            }
            catch (Exception ex)
            {
                MyMessageBox.ErrorOk("User Creation -Failed\n" +
                                ex.Message, "Error");
            }

        }

        private int _TabAccountIndexProperty;
        public int TabAccountIndexProperty
        {
            get { return _TabAccountIndexProperty; }
            set
            {
                _TabAccountIndexProperty = value;
                RaisePropertyChanged("TabAccountIndexProperty");
            }
        }
        #endregion
    }



}